using APITransLib.Contracts;
using System.Collections.Concurrent;

namespace ChatWithMulitAIServer.Services;

public class ChatStore
{
    private readonly ConcurrentDictionary<string, UserDto> _users = new();
    private readonly ConcurrentDictionary<string, GroupDto> _groups = new();
    private readonly ConcurrentDictionary<string, MessageDto> _messages = new();

    public UserDto CreateUser(string displayName)
    {
        var id = Guid.NewGuid().ToString("N");
        var user = new UserDto { Id = id, DisplayName = displayName };
        _users[id] = user;
        return user;
    }

    public GroupDto CreateGroup(string name, IEnumerable<string> memberIds)
    {
        var id = Guid.NewGuid().ToString("N");
        var group = new GroupDto { Id = id, Name = name, MemberUserIds = memberIds.Distinct().ToList() };
        _groups[id] = group;
        return group;
    }

    public GroupDto? GetGroup(string id) => _groups.TryGetValue(id, out var g) ? g : null;
    public UserDto? GetUser(string id) => _users.TryGetValue(id, out var u) ? u : null;

    public MessageDto AddMessage(string fromUserId, string? toUserId, string? toGroupId, MessageKind kind, string content)
    {
        var id = Guid.NewGuid().ToString("N");
        var msg = new MessageDto
        {
            Id = id,
            FromUserId = fromUserId,
            ToUserId = toUserId,
            ToGroupId = toGroupId,
            Kind = kind,
            Content = content,
            SentAt = DateTimeOffset.UtcNow
        };
        _messages[id] = msg;
        return msg;
    }

    public IEnumerable<MessageDto> GetMessagesForUser(string userId, int skip, int take)
        => _messages.Values
            .Where(m => m.ToUserId == userId || (m.ToGroupId != null && _groups.TryGetValue(m.ToGroupId, out var g) && g.MemberUserIds.Contains(userId)))
            .OrderBy(m => m.SentAt)
            .Skip(skip).Take(take);

    public IEnumerable<MessageDto> GetMessagesForGroup(string groupId, int skip, int take)
        => _messages.Values
            .Where(m => m.ToGroupId == groupId)
            .OrderBy(m => m.SentAt)
            .Skip(skip).Take(take);
}
